package net.freestu.sola.web.parser.PageParse.PageScore;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;


import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

/**
 * 1.形成一个Hash表. 元素为： id-->url.redirect-->score 
 *                 pageinfos id-->Info  
 * 2.形成一个附加分队列。 
 * 3.对Hash表的score进行修改。
 * 4.然后对page.xml的score进行修改。
 * @author 秋刀鱼的滋味
 * 
 */
public class PageScorer {

	private Map<Integer,Info> pageinfos = new HashMap<Integer, Info>();

	
	/**
	 * 这个变量是将URL-->id.用与通过URL查找id
	 */
	private Map regedit=new HashMap<String,Integer>();
	private List<IdScore> plusscoque;
	
	public PageScorer(){
		
		pageinfos=generatePageInfos(); 
		plusscoque=generateQueue();
		//if(plusscoque==null){
		//	System.out.println("plusscoque为null");
		//	System.exit(0);
		//}
		//System.out.println(plusscoque);
		calculate();
		
		Set keyset=pageinfos.keySet();
		Iterator it=keyset.iterator();
		
	    while(it.hasNext()){
	    	
	    	int ii=(Integer)it.next();
	    	Info info=pageinfos.get(ii);
	    	System.out.println("ID:"+ii+"  SCORE:"+info.getScore());
	    	
	    }
	}
	
	
	
	/**
	 * 生成Map,id-->url,redirect-->score
	 * 这个里同时也生成一个register。
	 * @return
	 */
	public Map generatePageInfos() {
		// public static void generatePageInfos(){

		String textXml = readXML();

		SAXBuilder builder = new SAXBuilder();// 创建解析器。

		Document doc = null;// 特别指定为XML文档
		Reader in = new StringReader(textXml);
		try {
			doc = builder.build(in);// 创建XML文档
			Element root = doc.getRootElement();// (page-infos)

			List pages = root.getChildren();// (page)的集合

			for (Iterator pageit = pages.iterator(); pageit.hasNext();) {// page进行历遍

				Element pageelm = (Element) pageit.next();// 是<page>的元素
				List info = pageelm.getChildren();

				//第二重------------------------------------
				int  id=0;
				String url = "";
				String redirect = "";
				double score=0;
				List al=new ArrayList(); 
				
				for (Iterator infoit = info.iterator(); infoit.hasNext();) {// 历遍<page>中的元素。
					
					Element el = (Element) infoit.next();

					if (el.getName().equals("id")) {// 得到name

						String i = el.getText();
						id = Integer.valueOf(i);
						
						// 1得到值。
					}else if (el.getName().equals("url")) {
						// System.out.println(el.getText());
						// 这个地方其实需要进行null排除。
						//这个地方有可能是<url/>,但这种情况不容易出现。
						
						String u = el.getText();
						url = u;

					}else if (el.getName().equals("redirect")) {
						String r = el.getText();
						redirect = r;
					}else if (el.getName().equals("score")) {

						String s = el.getText();
						
						//System.out.println("分数："+s);
						
						score = Double.valueOf(s);
						
						//System.out.println("分数："+score);
					}else if(el.getName().equals("link")){
						
						List l1 = el.getChildren();
						
						for (Iterator itl1 = l1.iterator(); itl1.hasNext();){
							
							Element e11 = (Element) itl1.next();
							
							if(e11.getName().equals("pagelinks")){
								
								String s=e11.getText();
								String[] ss=s.split("\\\\");
								for(String str:ss){
									
									//System.out.println(str);
									al.add(str);
							 }
							}else{
								continue;
							}
						}
						
					}else{
						continue;
					}
					
				}
					Info inn = new Info(url, redirect, score,al);
					
					System.out.println("-------------");
					System.out.println("id:" + id);
					System.out.println("url:" + url);
					System.out.println("redirect:" + redirect);
					System.out.println("score:" + score);

					pageinfos.put(id, inn);
					
					if(url.equals(redirect)){
					  regedit.put(url,id);
					  
					  //System.out.println("在regedit中放入："+url+":"+id);
					  
					}else{
					  regedit.put(url,id);
					  regedit.put(redirect,id);
					  //System.out.println("在regedit中放入："+url+":"+id);
					  //System.out.println("在regedit中放入："+redirect+":"+id);
					}
			}
			return pageinfos;

		} catch (IOException ex) {
			ex.printStackTrace();
			return null;
		} catch (JDOMException ex) {
			ex.printStackTrace();
			return null;
		}
	}

	public String readXML() {

		try {
			FileReader fr = new FileReader(
					"C:\\Documents and Settings\\秋刀鱼的滋味\\桌面\\o1.xml"); // 创建一个FileReader对象
																		// 从磁盘读
			BufferedReader br = new BufferedReader(fr); // 创建一个BufferedReader对象

			String line = "";
			while (br.ready()) { // 如果文件准备好，就继续读
				line += br.readLine(); // 读一行
				// System.out.println(line); //输出来
			}
			br.close(); // 关闭流
			fr.close();
			return line;
		} catch (IOException ex) {
			ex.printStackTrace();
			return null;
		}
	}

	/**
	 * 形成外部链接指向所得的分数的队列。
	 * @return
	 */
	public ArrayList generateQueue(){
		
	    ArrayList<IdScore> al1=new ArrayList<IdScore>();//要返回的值。
	    
		Set keys=pageinfos.keySet();
		Iterator it=keys.iterator();
		
		while(it.hasNext()){//历遍pageinfos
		
		int id=(Integer)it.next();	
		Info info=pageinfos.get(id);//通过id取出一张页面的信息
		double scor=info.getScore();//通过信息（info）取出一张页面的预定义分数。
		List list=info.getLinks();//取出一张页面信息中的链接数组（这个地方有可能是null;）
		
		int size=list.size();//网页的多少。
		double litt=div(scor,size,3);//精度取到小数点后面三位
		
		//System.out.println("links"+list);//!!!!
		
		//这里有可能是list中为空!!!!!!!!!!!!!!!!!!
		if (list==null) continue;
		
		Iterator listit=list.iterator();
		
		while(listit.hasNext()){//历遍一个网页中的链接。
			
			//System.out.println("ddddddddddddddddd");
			
			String str=(String)listit.next();
			
			//System.out.println("取出了："+str);
			
			//System.out.println(regedit);
			
			//----------------历遍regedit
			
			//System.out.println("regedit大小："+regedit.values());
			//System.out.println(regedit.);
			
			//---------------
			
			
			
			if(!regedit.containsKey(str)) continue;//如果在网页库中没有链接。
			
			//System.out.println("靠靠靠靠");
			
			int theid=(Integer)regedit.get(str);//从String->id注册表中获取id
			
			IdScore is=new IdScore(theid,litt);
			
			//System.out.println("注意这个地方："+theid+":"+litt);
			
			 al1.add(is);
		 }
		}
		
		return al1;
	}
	
	private double div(double v1,double v2,int scale){
		if(scale<0){
		throw new IllegalArgumentException(
		"The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
		}
	
	
	
   
	
	
	/**
	 * 重新计算分,并加入到Hash中(pageinfos文件中)。
	 * @param agrs
	 */
	public void calculate(){
		
		
        Iterator it=plusscoque.iterator();
       
        
       //System.out.println("ssdsdfsadgfagfafafa");
        
        //System.out.println("ssssssssss"+it.next().getId());
        
        if (plusscoque==null) System.out.println("plusscoque为空");
        
		while(it.hasNext()){
			
			 // System.out.println("ssdsdfsadgfagfafafa");
			//System.out.println("ddddddddddddddddddddddddddd");
		        
			
			IdScore is=(IdScore)it.next();
			int id=is.getId();//加分的ID
			double score=is.getScore();//要加的分数
			
			Info info=pageinfos.get(id);//???这个地方会不会出现对象从Hash中取出来了后不再是那个对象了呢？
			double d=info.getScore();
			double s=score+d;
			
			System.out.println("加入分数："+id+"---"+s);
			
			info.setScore(s);//将新的数据存入其中。??这个地方将两个double数据相加，会不会出现小数点后的位数的问题。
		}
	}
	
	
	
	public static void main(String[] agrs) {

		PageScorer ps = new PageScorer();
		
	}

}
